package com.djnt.catering;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import android.content.Context;
import android.content.res.Resources;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.djnt.catering.QuickQueryStack.IQuery;
import com.djnt.catering.QuickQueryStack.ItemQuery;

public class AllCitiesAdapter extends BaseAdapter {

	private LayoutInflater mInflater;
	static final int SIZE_OF_CITY = 7;
	private QuickQueryStack mSubQuery;

	static StartupThread mStartupThread;

	static class StartupThread extends Thread implements IQuery {
		Resources mRes;
		private HashMap<String, Integer> province_map;
		private HashMap<String, Integer> cities_map;
		private String[] province_array;
		ArrayList<Integer> mData;
		private QuickQueryStack mQuery;

		public StartupThread(Resources res) {
			// TODO Auto-generated constructor stub
			mRes = res;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			synchronized (this) {
				Resources res = mRes;
				province_array = res.getStringArray(R.array.province_array);
				province_map = new HashMap<String, Integer>();
				int i;
				for (i = 0; i < province_array.length; i++) {
					province_map.put(province_array[i], i + 1);
				}
				LoadCities();
				mQuery = new QuickQueryStack(this, cities_map.entrySet());
			}
		}

		private void LoadCities() {
			// TODO Auto-generated method stub
			Resources res = mRes;
			String[] ss = res.getStringArray(R.array.cities_array);
			cities_map = new HashMap<String, Integer>();
			for (int i = 0; i < ss.length; i++) {
				String s = ss[i];
				int j = s.indexOf(':');
				String key = s.substring(0, j);
				String[] value = s.substring(j + 1).split(",");
				int owner_id = province_map.get(key);
				for (String s1 : value) {
					cities_map.put(s1, owner_id);
				}
			}
		}

		@Override
		public String[] getText(Object it) {
			// TODO Auto-generated method stub
			Entry<String, Integer> s = (Entry<String, Integer>) it;
			String key = s.getKey();
			Integer owner_id = s.getValue();
			String province = province_array[owner_id - 1];
			return new String[] { key, province };
		}

	}

	public Entry<String, Integer> getItemEntry(int position) {
		// TODO Auto-generated method stub
		return (Entry<String, Integer>) getQuery().getItemEntry(position);
	}

	static void onStartup(Resources res) {
		mStartupThread = new StartupThread(res);
		mStartupThread.start();
	}

	AllCitiesAdapter(Context context) {
		mInflater = LayoutInflater.from(context);
		synchronized (mStartupThread) {
			mStartupThread.mQuery.onTextChanged("");
		}
	}

	public int getCount() {
		return getQuery().getCount();
	}

	private QuickQueryStack getQuery() {
		synchronized (mStartupThread) {
			if (mSubQuery != null) {
				return mSubQuery;
			}
			return mStartupThread.mQuery;
		}
	}

	/**
	 * Since the data comes from an array, just returning the index is sufficent
	 * to get at the data. If we were using a more complex data structure, we
	 * would return whatever object represents one row in the list.
	 * 
	 * @see android.widget.ListAdapter#getItem(int)
	 */
	public Object getItem(int position) {
		return position;
	}

	/**
	 * Use the array index as a unique id.
	 * 
	 * @see android.widget.ListAdapter#getItemId(int)
	 */
	public long getItemId(int position) {
		return position;
	}

	/**
	 * Make a view to hold each row.
	 * 
	 * @see android.widget.ListAdapter#getView(int, android.view.View,
	 *      android.view.ViewGroup)
	 */
	public View getView(int position, View convertView, ViewGroup parent) {
		// A ViewHolder keeps references to children views to avoid
		// unneccessary calls
		// to findViewById() on each row.

		// When convertView is not null, we can reuse it directly, there is
		// no need
		// to reinflate it. We only inflate a new View when the convertView
		// supplied
		// by ListView is null.
		if (convertView == null) {
			convertView = mInflater.inflate(
					android.R.layout.simple_list_item_2, null);
		}

		// Bind the data efficiently with the holder.
		TextView t1 = (TextView) convertView.findViewById(android.R.id.text1);
		TextView t2 = (TextView) convertView.findViewById(android.R.id.text2);
		synchronized (mStartupThread) {
			Entry<String, Integer> index = (Entry<String, Integer>) getQuery()
					.getItemEntry(position);
			int[] match = getQuery().getItemMatchData(position);
			t1.setText(forHtml(index.getKey(), match[0]));
			t2.setText(forHtml(
					mStartupThread.province_array[index.getValue() - 1],
					match[1]));
		}

		return convertView;
	}

	private CharSequence forHtml(String key, int value) {
		if (value == 0) {
			return key;
		}
		int start = value & 0xffff;
		int end = value >> 16;
		String t1 = key.substring(0, start);
		String t2 = key.substring(start, end);
		String t3 = key.substring(end);
		return Html
				.fromHtml(t1 + "<font color=\"blue\">" + t2 + "</font>" + t3);
	}

	static class myItemQuery implements ItemQuery {
		String mText;

		public myItemQuery(String t) {
			// TODO Auto-generated constructor stub
			mText = t;
		}

		@Override
		public boolean match(Object o) {
			// TODO Auto-generated method stub
			synchronized (mStartupThread) {
				Entry<String, Integer> s = (Entry<String, Integer>) o;
				int j = s.getValue();
				String t = mStartupThread.province_array[j - 1];
				return mText.equals(t);
			}
		}
	}

	void queryWithProvince(String t) {
		// TODO Auto-generated method stub
		if (!TextUtils.isEmpty(t)) {
			synchronized (mStartupThread) {
				mSubQuery = mStartupThread.mQuery.query(new myItemQuery(t));
			}
			this.notifyDataSetChanged();
		}
	}

	void onTextChanged(String strInput) {
		getQuery().onTextChanged(strInput);
		this.notifyDataSetChanged();
	}
}
